FastAPI একটি অত্যন্ত দ্রুত এবং কার্যক্ষম ফ্রেমওয়ার্ক, তবে কিছু নির্দিষ্ট কৌশল এবং টেকনিক ব্যবহার করে তার পারফরম্যান্স আরও বাড়ানো যেতে পারে। এটি সঠিকভাবে কনফিগার এবং অপটিমাইজ করার মাধ্যমে বড় আকারের প্রোডাকশন অ্যাপ্লিকেশনেও উচ্চ পারফরম্যান্স নিশ্চিত করা সম্ভব।
এই গাইডে, আমরা FastAPI এর পারফরম্যান্স অপটিমাইজেশন টিপস এবং টেকনিকসমূহ আলোচনা করব।
1. Asynchronous Programming ব্যবহার করা
FastAPI asynchronous programming সমর্থন করে, যা অ্যাপ্লিকেশনকে উচ্চ লোড হ্যান্ডল করার জন্য আরও কার্যকর করে তোলে। async এবং await ব্যবহার করে আপনি ফাংশনগুলো non-blocking করতে পারেন।
উদাহরণ: Asynchronous Endpoint
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/async_example")
async def async_example():
await asyncio.sleep(2)
return {"message": "This is an async response"}
এখানে, asyncio.sleep(2) এর মাধ্যমে আমরা ফাংশনটি আসিনক্রোনাস করি, যা সার্ভারের অন্যান্য রিকোয়েস্ট ব্লক না করে পারফরম্যান্স বাড়ায়।
কেন এটি পারফরম্যান্স বাড়ায়?
- Non-blocking I/O অপারেশনগুলির জন্য অ্যাসিঙ্ক্রোনাস কোড কার্যকর, বিশেষ করে যখন অ্যাপ্লিকেশন ডাটাবেস বা নেটওয়ার্কের সাথে যোগাযোগ করছে।
2. Uvicorn Worker সংখ্যা বাড়ানো
FastAPI অ্যাপ্লিকেশন চালানোর জন্য Uvicorn ব্যবহার করা হয়। Uvicorn তে worker সংখ্যা বাড়ানোর মাধ্যমে আপনি আরও রিকোয়েস্ট প্রক্রিয়া করতে পারেন।
উদাহরণ: Uvicorn Workers কনফিগার করা
uvicorn app:app --workers 4 --host 0.0.0.0 --port 8000
এখানে --workers 4 দিয়ে আমরা ৪টি worker প্রসেস চালাচ্ছি, যা সিস্টেমের মাল্টি-কোর প্রসেসর ব্যবহার করে আরও বেশি রিকোয়েস্ট হ্যান্ডল করার ক্ষমতা দেয়।
কেন এটি পারফরম্যান্স বাড়ায়?
- একাধিক worker ব্যবহার করলে সার্ভার একসাথে বেশ কয়েকটি রিকোয়েস্ট প্রক্রিয়া করতে সক্ষম হয়, যা স্কেলেবিলিটি উন্নত করে।
3. Caching ব্যবহারের মাধ্যমে পারফরম্যান্স বাড়ানো
ডাটা বা রেসপন্স ক্যাশিং ব্যবহার করে আপনি অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করতে পারেন, বিশেষ করে যখন একই ডাটা একাধিকবার অনুরোধ করা হয়।
উদাহরণ: Simple Cache Example
FastAPI তে cache ব্যবহারের জন্য cachetools বা অন্য কাস্টম ক্যাশিং লাইব্রেরি ব্যবহার করতে পারেন।
from fastapi import FastAPI
from cachetools import cached, TTLCache
# Create a cache object with max size and time-to-live (TTL)
cache = TTLCache(maxsize=100, ttl=300)
app = FastAPI()
@cached(cache)
@app.get("/cached_item/{item_id}")
async def get_cached_item(item_id: int):
# Simulate a time-consuming operation
return {"item_id": item_id, "data": "This is a cached response"}
এখানে, আমরা cachetools লাইব্রেরি ব্যবহার করে রেসপন্স ক্যাশিং সেটআপ করেছি।
কেন এটি পারফরম্যান্স বাড়ায়?
- ক্যাশিং একই ডাটা বারবার প্রসেস না করানোর মাধ্যমে সার্ভার রেসপন্স টাইম কমিয়ে দেয় এবং সার্ভারের লোড কমায়।
4. Database Query Optimization
ডাটাবেসের পারফরম্যান্স অপটিমাইজেশন অত্যন্ত গুরুত্বপূর্ণ, বিশেষ করে যখন অ্যাপ্লিকেশন বড় স্কেলে কাজ করছে। কিছু সাধারণ টিপস:
- Indexed Columns: ডাটাবেসে প্রয়োজনীয় কলামে ইনডেক্স ব্যবহার করুন।
- Pagination: একসাথে বড় পরিমাণ ডাটা ফিরিয়ে না দিয়ে pagination ব্যবহার করুন।
- SQLAlchemy Optimization:
selectinload,joinedload, এবংnoloadব্যবহার করে ডাটাবেসের query optimization করতে পারেন।
উদাহরণ: SQLAlchemy Query Optimization
from fastapi import FastAPI
from sqlalchemy.orm import selectinload
from . import models, database
app = FastAPI()
@app.get("/items/")
async def get_items():
session = database.SessionLocal()
items = session.query(models.Item).options(selectinload(models.Item.details)).all()
return items
এখানে selectinload ব্যবহার করা হয়েছে, যা সম্পর্কিত ডাটা দ্রুত লোড করতে সাহায্য করে এবং একাধিক জিজ্ঞাসার সংখ্যা কমিয়ে আনে।
5. Request Validation ও Model Optimization
FastAPI তে Pydantic মডেল ব্যবহার করে ডাটা ভ্যালিডেশন করা হয়, তবে আপনি কিছু optimization টেকনিক ব্যবহার করে পারফরম্যান্স আরও বাড়াতে পারেন:
- Field Default Values: যদি কোনো ফিল্ডের ডিফল্ট মান থাকে, তবে তা নিশ্চিত করুন।
- Use
@cached_propertyfor Computed Fields: পিড্যান্টিক মডেলের গণনা করা ফিল্ডগুলো ক্যাশ করতে পারেন।
উদাহরণ: Pydantic Model Optimization
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
tax: float | None = None
@property
def price_with_tax(self):
return self.price + (self.tax or 0)
এখানে, price_with_tax একটি গণনা করা ফিল্ড এবং এতে ক্যাশিং বা প্রিসেট ভ্যালু ব্যবহার করতে পারেন।
কেন এটি পারফরম্যান্স বাড়ায়?
@propertyএবং@cached_propertyব্যবহারের মাধ্যমে আপনি পুনরায় গণনা থেকে বাঁচতে পারেন এবং দ্রুত রেসপন্স পেতে পারেন।
6. JSON Serialization Optimization
FastAPI ডিফল্টভাবে JSON রেসপন্স সিরিয়ালাইজ করার জন্য jsonable_encoder ব্যবহার করে, তবে আপনি এটি আরও দ্রুত করতে orjson ব্যবহার করতে পারেন।
উদাহরণ: orjson ব্যবহার করে JSON Serialization অপটিমাইজেশন
pip install orjson
from fastapi import FastAPI
import orjson
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/optimized_json/")
def optimized_json():
return JSONResponse(content=orjson.dumps({"message": "Fast JSON response"}))
এখানে orjson ব্যবহার করা হয়েছে যা দ্রুত JSON সিরিয়ালাইজেশন প্রদান করে।
কেন এটি পারফরম্যান্স বাড়ায়?
- orjson খুব দ্রুত JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন প্রদান করে, যা পারফরম্যান্সে উল্লেখযোগ্য উন্নতি ঘটাতে সহায়ক।
7. Background Tasks ব্যবহারের মাধ্যমে Heavy Computation Offload করা
যদি আপনার অ্যাপ্লিকেশন হেভি কম্পিউটেশনাল কাজ (যেমন ফাইল প্রসেসিং বা ডাটা বিশ্লেষণ) করছে, তবে আপনি background tasks ব্যবহার করতে পারেন যাতে এই কাজগুলি background এ চলে এবং ইউজারের জন্য রেসপন্স দ্রুত হয়।
উদাহরণ: Background Task
from fastapi import FastAPI, BackgroundTasks
app = FastAPI()
def process_data(data: str):
# Heavy computation
print(f"Processing data: {data}")
@app.post("/start_task/")
async def start_task(background_tasks: BackgroundTasks, data: str):
background_tasks.add_task(process_data, data)
return {"message": "Task started in the background"}
এখানে background_tasks ব্যবহৃত হয়েছে যাতে কম্পিউটেশনাল কাজ ব্যাকগ্রাউন্ডে চলে।
FastAPI তে Performance Optimization একটি গুরুত্বপূর্ণ বিষয়, বিশেষ করে যখন আপনার অ্যাপ্লিকেশন বড় স্কেলে চলে। এর জন্য আপনি asynchronous programming, caching, Uvicorn workers, query optimization, background tasks, এবং serialization optimizations ব্যবহার করতে পারেন। এই কৌশলগুলো ব্যবহার করে আপনি আপনার FastAPI অ্যাপ্লিকেশনকে আরও দ্রুত এবং স্কেলেবল করতে পারবেন।
FastAPI একটি আধুনিক ওয়েব ফ্রেমওয়ার্ক, যা Asynchronous Programming এবং Performance Optimization এ অনেক সুবিধা প্রদান করে। FastAPI এর মাধ্যমে আপনি উচ্চ পারফরম্যান্সের অ্যাপ্লিকেশন তৈরি করতে পারেন, যেখানে অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং-এর সাহায্যে বেশি স্কেলেবিলিটি এবং দ্রুত রেসপন্স পাওয়া যায়।
এই গাইডে, আমরা Asynchronous Programming এবং Performance Optimization এর কিছু গুরুত্বপূর্ণ দিক নিয়ে আলোচনা করব এবং FastAPI এর মাধ্যমে কিভাবে এগুলো কার্যকরভাবে ব্যবহার করা যায় তা দেখব।
১. Asynchronous Programming: FastAPI-তে কীভাবে কাজ করে
FastAPI Asynchronous Programming সমর্থন করে, যার ফলে একাধিক I/O অপারেশন (যেমন ডাটাবেস কল, ফাইল সিস্টেম অপারেশন) একই সময়ে রান করতে পারে। এটি সার্ভারের স্কেলেবিলিটি এবং পারফরম্যান্স বাড়াতে সহায়ক।
Asynchronous Function
FastAPI তে অ্যাসিঙ্ক্রোনাস ফাংশন তৈরি করতে async এবং await কিওয়ার্ড ব্যবহার করা হয়। এটি ডাটা প্রসেস করার সময় নেটওয়ার্ক বা ডাটাবেস কল করার জন্য থ্রেড ব্লক না করে অন্য কাজ করতে সাহায্য করে।
from fastapi import FastAPI
import asyncio
app = FastAPI()
@app.get("/")
async def read_root():
await asyncio.sleep(2) # Simulating I/O operation (e.g. DB or API call)
return {"message": "Hello, FastAPI!"}
এখানে, async def ব্যবহার করে asynchronous function তৈরি করা হয়েছে। await ব্যবহার করে I/O অপারেশনগুলো নিষ্ক্রিয় রাখা হচ্ছে, যাতে সার্ভার অন্যান্য রিকোয়েস্টগুলো প্রসেস করতে পারে।
Asynchronous I/O Operation
যখন অ্যাসিঙ্ক্রোনাস ফাংশন ব্যবহার করা হয়, তখন I/O অপারেশন (যেমন ডাটাবেস, HTTP কল) অপেক্ষা করার সময় CPU ফ্রি থাকে এবং অন্য রিকোয়েস্ট প্রসেস করা যায়। এটি হাইপারফরম্যান্স ওয়েব অ্যাপ্লিকেশন তৈরির জন্য খুবই কার্যকরী।
২. Performance Optimization Techniques in FastAPI
FastAPI ব্যবহার করে পারফরম্যান্স অপটিমাইজ করার জন্য কিছু কৌশল অবলম্বন করা যেতে পারে। এখানে কিছু মূল টিপস দেওয়া হলো:
১. Use Asynchronous Libraries
যখন আপনি ডাটাবেস, ফাইল সিস্টেম, বা নেটওয়ার্কে কোনো I/O অপারেশন করছেন, তখন asynchronous libraries ব্যবহার করা উচিত। এটি সার্ভারের অন্যান্য রিকোয়েস্ট প্রসেসিং থামিয়ে না রেখে, অপ্রয়োজনীয় বিলম্ব এড়াতে সাহায্য করবে।
উদাহরণ: Asynchronous Database Call
from fastapi import FastAPI
import databases
DATABASE_URL = "sqlite:///./test.db"
database = databases.Database(DATABASE_URL)
app = FastAPI()
@app.on_event("startup")
async def startup():
await database.connect()
@app.on_event("shutdown")
async def shutdown():
await database.disconnect()
@app.get("/items/{item_id}")
async def get_item(item_id: int):
query = "SELECT * FROM items WHERE id = :item_id"
item = await database.fetch_one(query, values={"item_id": item_id})
return item
এখানে databases লাইব্রেরি ব্যবহার করা হয়েছে যা অ্যাসিঙ্ক্রোনাস ডাটাবেস কল তৈরি করতে সাহায্য করে।
২. Limit Response Size
বড় আকারের রেসপন্স অ্যাপ্লিকেশনের পারফরম্যান্স হ্রাস করতে পারে। তাই, রেসপন্সের আকার সীমাবদ্ধ রাখুন।
উদাহরণ: Limit Response Size
from fastapi import FastAPI
from typing import List
app = FastAPI()
@app.get("/items/", response_model=List[str])
async def get_items():
# Simulating a large data response
items = ["item1", "item2", "item3", "item4", "item5"]
return items[:3] # Limiting the response to the first 3 items
এখানে, রেসপন্সের আকার 3 আইটেম পর্যন্ত সীমাবদ্ধ করা হয়েছে।
৩. Use Background Tasks
ফাস্টএপিআই তে ব্যাকগ্রাউন্ড টাস্ক ব্যবহার করা যায়। যেমন, দীর্ঘ সময় ধরে চলা কাজগুলো, যেগুলি রিকোয়েস্ট প্রসেসিং থেকে আলাদা হতে পারে, ব্যাকগ্রাউন্ড টাস্ক হিসেবে চালানো যায়।
উদাহরণ: Background Tasks
from fastapi import FastAPI, BackgroundTasks
app = FastAPI()
def write_log(message: str):
with open("log.txt", "a") as log:
log.write(message)
@app.get("/")
async def root(background_tasks: BackgroundTasks):
background_tasks.add_task(write_log, "New request received!\n")
return {"message": "Hello, World!"}
এখানে, write_log ফাংশনটি ব্যাকগ্রাউন্ডে চলে, এবং background_tasks.add_task এর মাধ্যমে এই কাজটি আলাদা থ্রেডে করা হয়।
৪. Use Caching
ক্যাশিং একটি কার্যকর পদ্ধতি যা ডেটা পুনরায় প্রসেসিং থেকে রক্ষা করে এবং API-এর দ্রুত রেসপন্স প্রদান করে। FastAPI তে Redis বা Memcached ব্যবহার করা যেতে পারে।
উদাহরণ: Caching with Redis
import redis
from fastapi import FastAPI
app = FastAPI()
redis_client = redis.Redis(host='localhost', port=6379, db=0)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
cached_item = redis_client.get(item_id)
if cached_item:
return {"item_id": item_id, "cached": True, "item": cached_item.decode()}
# Simulating a DB call and caching it
item = {"name": f"Item {item_id}", "price": 100 + item_id}
redis_client.set(item_id, str(item))
return {"item_id": item_id, "cached": False, "item": item}
এখানে, Redis ক্যাশিং ব্যবহার করে ডাটাবেস কল কমানো হয়েছে।
৫. Optimize Middleware Usage
FastAPI তে বিভিন্ন Middleware ব্যবহার করা হয়। তবে, অতিরিক্ত Middleware ব্যবহারে পারফরম্যান্স ক্ষতিগ্রস্ত হতে পারে। তাই, Middleware শুধুমাত্র প্রয়োজনীয় ক্ষেত্রেই ব্যবহার করা উচিত।
৩. Concurrency and Parallelism in FastAPI
FastAPI অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং সমর্থন করে, যার মাধ্যমে আপনি একাধিক কাজ একসাথে রান করাতে পারেন। FastAPI অ্যাসিঙ্ক্রোনাস I/O সমর্থন করে, যা অ্যাপ্লিকেশনকে concurrent এবং parallel টাস্ক পরিচালনা করার সুবিধা দেয়।
উদাহরণ: Concurrency in FastAPI
from fastapi import FastAPI
import asyncio
app = FastAPI()
async def simulate_io_task(task_id: int):
await asyncio.sleep(2) # Simulating I/O task (e.g., DB call)
return f"Task {task_id} completed"
@app.get("/")
async def perform_tasks():
tasks = [simulate_io_task(i) for i in range(1, 6)]
results = await asyncio.gather(*tasks)
return {"results": results}
এখানে, asyncio.gather ব্যবহার করা হয়েছে যাতে একাধিক I/O টাস্ক একসাথে সম্পন্ন করা যায় এবং অ্যাসিঙ্ক্রোনাসভাবে তাদের ফলাফল সংগ্রহ করা যায়।
FastAPI অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং এবং পারফরম্যান্স অপটিমাইজেশনের জন্য অত্যন্ত কার্যকরী। আপনি Asynchronous Programming ব্যবহার করে ডাটা প্রসেসিং দ্রুত করতে পারেন এবং Performance Optimization এর জন্য বিভিন্ন কৌশল যেমন ক্যাশিং, লিমিটিং রেসপন্স সাইজ, ব্যাকগ্রাউন্ড টাস্ক ইত্যাদি ব্যবহার করতে পারেন। FastAPI তে অ্যাসিঙ্ক্রোনাস ফাংশন, হাই পারফরম্যান্স এবং স্কেলেবিলিটি নিশ্চিত করার জন্য পারফেক্ট সাপোর্ট রয়েছে।
Caching হল এমন একটি প্রযুক্তি যা ডেটা বা রেসপন্স সংরক্ষণ করে এবং পুনরায় ব্যবহারের জন্য দ্রুত অ্যাক্সেস প্রদান করে। ফাস্টএপিআই (FastAPI) তে ক্যাশিং ব্যবহারের মাধ্যমে আপনি সার্ভারের লোড কমাতে এবং অ্যাপ্লিকেশনের পারফরম্যান্স দ্রুত করতে পারেন। ক্যাশিং সাধারণত ডেটাবেস কুয়েরি, API রেসপন্স, বা অন্য কোনো ব্যয়বহুল প্রসেসের ফলাফল সংরক্ষণ করতে ব্যবহৃত হয়।
FastAPI তে ক্যাশিং বাস্তবায়ন করার জন্য বিভিন্ন প্রযুক্তি ব্যবহার করা যেতে পারে, যেমন Redis, Memcached, বা ইন-মেমরি ক্যাশিং।
এই গাইডে আমরা দেখব কিভাবে Redis ক্যাশিং ব্যবহার করে FastAPI অ্যাপ্লিকেশনের পারফরম্যান্স বৃদ্ধি করা যায়।
কেন Caching ব্যবহার করবেন?
কিছু কারণে ক্যাশিং অত্যন্ত গুরুত্বপূর্ণ:
- পারফরম্যান্স বৃদ্ধি: ক্যাশিং দ্রুত রেসপন্সের মাধ্যমে সার্ভারের লোড কমায়।
- ডাটাবেস কুয়েরি অপ্টিমাইজেশন: ক্যাশিং ব্যবহারের মাধ্যমে একাধিক কুয়েরি ডাটাবেসে পাঠানো এড়ানো যায়, যা ডাটাবেসের লোড কমায়।
- API কল কমানো: বাইরের API কলগুলো ক্যাশে রেখে কম করা যায়।
- উচ্চ ট্রাফিক পরিচালনা: উচ্চ ট্রাফিক সময়ে দ্রুত রেসপন্স প্রদান করে, সার্ভারের লোড কমায়।
FastAPI তে Redis ব্যবহার করে Caching
Redis হলো একটি ইন-মেমরি ডেটাবেস যা ক্যাশিং এবং ডেটা স্টোরেজের জন্য খুবই জনপ্রিয়। FastAPI তে Redis ব্যবহার করে ডেটা ক্যাশিং করা যায়।
১. Redis ইনস্টল করা
Redis ব্যবহার করার জন্য আপনাকে প্রথমে redis এবং aioredis লাইব্রেরি ইনস্টল করতে হবে।
pip install redis aioredis
২. FastAPI অ্যাপ্লিকেশন তৈরি এবং Redis ক্যাশিং ব্যবহার করা
এখন আমরা Redis ক্যাশিং ব্যবহার করে FastAPI অ্যাপ তৈরি করব। এখানে আমরা aioredis লাইব্রেরি ব্যবহার করব, যা অ্যাসিঙ্ক্রোনাস Redis ক্লায়েন্ট।
from fastapi import FastAPI
import aioredis
import json
app = FastAPI()
# Redis সেটআপ
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
# Redis সংযোগ তৈরি
async def get_redis():
return await aioredis.create_redis_pool((REDIS_HOST, REDIS_PORT), db=REDIS_DB)
@app.on_event("startup")
async def startup():
app.state.redis = await get_redis()
@app.on_event("shutdown")
async def shutdown():
app.state.redis.close()
await app.state.redis.wait_closed()
@app.get("/items/{item_id}")
async def get_item(item_id: int):
redis = app.state.redis
# ক্যাশে চেক করা
cached_item = await redis.get(f"item:{item_id}")
if cached_item:
# ক্যাশে থাকলে, ক্যাশ থেকে ডেটা রিটার্ন
return {"item_id": item_id, "cached": True, "item": json.loads(cached_item)}
# ক্যাশে না থাকলে, নতুন ডেটা তৈরি করা
item = {"name": f"Item {item_id}", "price": 100 + item_id}
# নতুন ডেটা ক্যাশে রাখা
await redis.set(f"item:{item_id}", json.dumps(item), expire=60) # 60 সেকেন্ডের জন্য ক্যাশে রাখবেন
return {"item_id": item_id, "cached": False, "item": item}
এখানে:
get_redis: Redis থেকে সংযোগ তৈরি করা।app.state.redis: FastAPI অ্যাপ্লিকেশনের স্টেটে Redis সংযোগ রাখা।expire=60: ফাইলটি 60 সেকেন্ডের জন্য Redis ক্যাশে রাখার জন্যexpireব্যবহার করা হয়েছে। এর মানে হল যে, 60 সেকেন্ড পরে ডেটাটি ক্যাশ থেকে মুছে যাবে।
৩. Redis ক্যাশে কিভাবে কাজ করছে
- ক্যাশে চেক করা: যখন
GET /items/{item_id}এন্ডপয়েন্টে রিকোয়েস্ট আসে, প্রথমে Redis ক্যাশে চেক করা হয় যে ডেটাটি আছে কিনা। - ক্যাশে ডেটা পাওয়া গেলে: যদি ক্যাশে ডেটা পাওয়া যায়, তবে সেই ডেটা রিটার্ন করা হয় এবং
cachedফিল্ডের মানTrueহবে। - ক্যাশে ডেটা না পাওয়া গেলে: যদি ক্যাশে ডেটা না পাওয়া যায়, তবে নতুন ডেটা তৈরি করা হয় এবং Redis ক্যাশে সংরক্ষণ করা হয়।
৪. Testing the Cache
১. প্রথম রিকোয়েস্ট:
GET /items/1
{
"item_id": 1,
"cached": false,
"item": {"name": "Item 1", "price": 101}
}
এখানে ক্যাশে ডেটা নেই, তাই নতুন ডেটা তৈরি করা হয়েছে এবং Redis ক্যাশে রাখা হয়েছে।
২. পরবর্তী রিকোয়েস্ট:
GET /items/1
{
"item_id": 1,
"cached": true,
"item": {"name": "Item 1", "price": 101}
}
এখন ক্যাশে ডেটা পাওয়া গেছে, তাই Redis থেকে ডেটা ফিরিয়ে দেয়া হয়েছে।
৫. Redis Cache Expiration
Redis ক্যাশে ডেটা expire করা যেতে পারে, যাতে নির্দিষ্ট সময় পর ডেটা মুছে যায়। FastAPI তে আমরা expire অপশন ব্যবহার করে এই কার্যকলাপ পরিচালনা করতে পারি, যেমন উপরে দেওয়া কোডে expire=60 ব্যবহার করা হয়েছে, যার মানে হল যে ডেটা 60 সেকেন্ড পর মুছে যাবে।
৬. Redis Error Handling
Redis সংযোগে কোনো ত্রুটি ঘটলে, আপনি ত্রুটির সাথে সঠিকভাবে কাজ করার জন্য কোডে Error Handling করতে পারেন। যেমন:
@app.get("/items/{item_id}")
async def get_item(item_id: int):
try:
redis = app.state.redis
# ক্যাশে চেক করা
cached_item = await redis.get(f"item:{item_id}")
if cached_item:
return {"item_id": item_id, "cached": True, "item": json.loads(cached_item)}
item = {"name": f"Item {item_id}", "price": 100 + item_id}
await redis.set(f"item:{item_id}", json.dumps(item), expire=60)
return {"item_id": item_id, "cached": False, "item": item}
except aioredis.RedisError as e:
return {"error": "Error connecting to Redis", "details": str(e)}
এখানে RedisError এর মাধ্যমে Redis সংযোগের ত্রুটি শনাক্ত করা হয়েছে।
Redis ক্যাশিং ব্যবহার করে FastAPI এর পারফরম্যান্স উন্নত করা যেতে পারে, বিশেষ করে বড় ডেটা এবং আই/ও অপারেশনের জন্য। Redis ক্যাশিং সার্ভারের লোড কমায় এবং রেসপন্স টাইম দ্রুত করে তোলে। আপনি expire, data validation, এবং error handling এর মতো গুরুত্বপূর্ণ বৈশিষ্ট্য ব্যবহার করে ক্যাশিং প্রক্রিয়া আরও উন্নত করতে পারেন। FastAPI তে Redis ক্যাশিং এক সহজ এবং কার্যকরী পদ্ধতি যা ওয়েব অ্যাপ্লিকেশনের স্কেলেবিলিটি এবং পারফরম্যান্স বৃদ্ধি করে।
FastAPI ব্যবহার করে যখন আপনি ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করেন, তখন সঠিক Database Query Optimization খুবই গুরুত্বপূর্ণ। এটি অ্যাপ্লিকেশনের পারফরম্যান্স এবং স্কেলেবিলিটি বৃদ্ধি করতে সাহায্য করে, বিশেষত যখন অ্যাপ্লিকেশনটি বড় হয় এবং ডাটাবেসের পরিমাণ অনেক বেড়ে যায়। সঠিক Query Optimization এর মাধ্যমে আপনি unnecessary database calls কমাতে, দ্রুততর রেসপন্স টাইম এবং কম রিসোর্স ব্যবহার করতে পারবেন।
এখানে আমরা কিছু জনপ্রিয় Database Query Optimization Techniques নিয়ে আলোচনা করব যা FastAPI অ্যাপ্লিকেশনে ব্যবহার করা যেতে পারে।
Step 1: Indexing
Indexing একটি ডাটাবেস অপটিমাইজেশন পদ্ধতি যেখানে আপনি একটি টেবিলের কলামে ইনডেক্স তৈরি করেন, যাতে সেখান থেকে ডাটা অনুসন্ধান দ্রুত হয়। এটি ডাটাবেসে সার্চ পারফরম্যান্স উন্নত করে।
উদাহরণ:
ধরা যাক আপনার একটি users টেবিল রয়েছে এবং আপনি email কলামে অনুসন্ধান করতে চান। তাহলে email কলামের জন্য ইনডেক্স তৈরি করা যেতে পারে।
CREATE INDEX idx_email ON users (email);
FastAPI-তে যদি SQLAlchemy ব্যবহার করেন, তাহলে আপনি Index ব্যবহার করে ইনডেক্স তৈরি করতে পারেন:
উদাহরণ: SQLAlchemy ইনডেক্স
from sqlalchemy import Column, Integer, String, Index
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String, unique=True)
__table_args__ = (
Index('idx_email', 'email'), # ইনডেক্স তৈরি
)
Step 2: Query Optimization (Select Only Required Fields)
একটি সাধারণ ভুল হলো select * from table ব্যবহার করা, যেখানে সমস্ত কলাম সিলেক্ট করা হয়। এটি অকারণে বড় ডাটা আনার কারণে অ্যাপ্লিকেশন স্লো হতে পারে। বরং, যেগুলি প্রয়োজন শুধু সেগুলি সিলেক্ট করুন।
উদাহরণ:
# Avoid select *
SELECT * FROM users WHERE id = 1;
এর পরিবর্তে:
# Select only required fields
SELECT id, name FROM users WHERE id = 1;
FastAPI তে SQLAlchemy ব্যবহার করার সময়, আপনি সঠিক ফিল্ডগুলো সিলেক্ট করতে পারেন:
from sqlalchemy.orm import Session
def get_user(db: Session, user_id: int):
return db.query(User.id, User.name).filter(User.id == user_id).first()
Step 3: Using Pagination for Large Result Sets
যখন আপনি ডাটাবেস থেকে বড় পরিমাণ ডাটা ফিরিয়ে আনতে চান, তখন পুরো ডাটার সব রেকর্ড একসাথে ফেরত না দিয়ে pagination (পৃষ্ঠা বিভাজন) ব্যবহার করা উচিত। এটি রেসপন্সের সাইজ ছোট করে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করে।
উদাহরণ: Pagination SQL Query
SELECT * FROM users LIMIT 10 OFFSET 0; -- First page (10 records)
SELECT * FROM users LIMIT 10 OFFSET 10; -- Second page (next 10 records)
FastAPI তে pagination যোগ করা:
from sqlalchemy.orm import Session
from fastapi import FastAPI, Depends
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
id: int
name: str
@app.get("/items/")
def get_items(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
items = db.query(Item).offset(skip).limit(limit).all()
return items
এখানে skip এবং limit প্যারামিটার ব্যবহার করে ডাটা পেজিনেশন করা হয়েছে।
Step 4: Eager Loading (Avoid N+1 Query Problem)
Eager Loading ডাটাবেসের সাথে সম্পর্কিত ডেটা একসাথে লোড করার প্রক্রিয়া। এটা N+1 Query Problem এড়াতে সাহায্য করে, যেখানে একাধিক রিকোয়েস্টের কারণে ডাটাবেসে অনেকগুলো অপ্রয়োজনীয় কুয়েরি চলে।
উদাহরণ:
ধরা যাক, আপনার User এবং Post টেবিলের মধ্যে একটি সম্পর্ক রয়েছে। যদি আপনি প্রতিটি ব্যবহারকারীর পোস্টগুলি আলাদাভাবে লোড করেন, তবে অনেকগুলি অতিরিক্ত কুয়েরি হবে। সেক্ষেত্রে Eager Loading ব্যবহার করুন।
# Avoid N+1 Query Problem
users = db.query(User).all()
for user in users:
print(user.posts) # This can trigger N+1 queries.
এটি সমাধান করার জন্য Eager Loading ব্যবহার করুন:
# Using Eager Loading (joinedload)
from sqlalchemy.orm import joinedload
users = db.query(User).options(joinedload(User.posts)).all()
for user in users:
print(user.posts) # No additional queries, posts are already loaded
এখানে joinedload ব্যবহার করে সম্পর্কিত ডাটা একসাথে লোড করা হচ্ছে।
Step 5: Query Caching
Query Caching ব্যবহার করে আপনি পুনরায় একি কুয়েরি করার সময়ে ডাটাবেসের থেকে নতুন করে ডাটা আনতে না গিয়ে পূর্বে কনজেস্ট করা ডাটা ব্যবহার করতে পারেন। এটি রেসপন্স টাইম কমিয়ে দেয় এবং ডাটাবেসের উপর চাপ কমায়।
উদাহরণ:
FastAPI তে Redis বা Memcached ব্যবহার করে আপনি কুয়েরি কেশিং করতে পারেন।
import redis
# Create a Redis client
cache = redis.StrictRedis(host='localhost', port=6379, db=0)
# Fetch cached data
cached_data = cache.get('some_query_result')
if not cached_data:
# Run the query if not cached
result = db.query(User).filter(User.id == 1).first()
cache.set('some_query_result', result)
else:
# Use cached data
result = cached_data
এখানে Redis ব্যবহার করে কুয়েরি কেশিং করা হয়েছে, যাতে প্রতিবার একি কুয়েরি না চালিয়ে কাঁচা ফলাফল ব্যবহার করা হয়।
Step 6: Database Connection Pooling
Database Connection Pooling হল একটি কৌশল যেখানে ডাটাবেস কানেকশনগুলোর পুনঃব্যবহার করা হয়, যাতে নতুন কানেকশন তৈরি করার প্রয়োজন না হয়। এটি ডাটাবেসের কর্মক্ষমতা উন্নত করতে সাহায্য করে।
উদাহরণ: SQLAlchemy Connection Pooling
from sqlalchemy import create_engine
DATABASE_URL = "postgresql://user:password@localhost/dbname"
engine = create_engine(DATABASE_URL, pool_size=10, max_overflow=20)
এখানে pool_size এবং max_overflow প্যারামিটার ব্যবহার করে কানেকশন পুল সেট করা হয়েছে।
Step 7: Use of EXPLAIN for Query Performance
ডাটাবেস কুয়েরির কার্যকারিতা পরীক্ষা করার জন্য EXPLAIN ব্যবহার করতে পারেন। এটি আপনাকে কুয়েরি প্ল্যান এবং অপটিমাইজেশন সম্পর্কে বিস্তারিত তথ্য প্রদান করে।
EXPLAIN SELECT * FROM users WHERE id = 1;
এটি কুয়েরির কার্যকারিতা বিশ্লেষণ করে এবং কোথায় অপটিমাইজেশন প্রয়োজন তা দেখায়।
FastAPI তে Database Query Optimization Techniques ব্যবহারের মাধ্যমে অ্যাপ্লিকেশনের পারফরম্যান্স অনেক ভালো করা যায়। সঠিক indexing, pagination, query optimization, eager loading, query caching, এবং connection pooling ব্যবহারের মাধ্যমে আপনি ডাটাবেসের কার্যক্ষমতা বৃদ্ধি করতে পারবেন এবং অ্যাপ্লিকেশনের রেসপন্স টাইম কমাতে পারবেন। FastAPI, SQLAlchemy, এবং অন্যান্য ডাটাবেস টুলস ব্যবহারের মাধ্যমে এই অপটিমাইজেশন কৌশলগুলো সহজেই বাস্তবায়ন করা সম্ভব।
FastAPI একটি দ্রুত, নিরাপদ এবং আধুনিক Python ওয়েব ফ্রেমওয়ার্ক, যা পণ্যভিত্তিক অ্যাপ্লিকেশন তৈরি করার জন্য অত্যন্ত উপযোগী। যখন আপনি FastAPI অ্যাপ্লিকেশন প্রোডাকশন পরিবেশে নিয়ে আসবেন, তখন আপনার অ্যাপ্লিকেশনটি নিরাপদ, স্কেলেবল, এবং কার্যকরী হওয়া জরুরি। এখানে, আমরা FastAPI অ্যাপ্লিকেশনকে production-ready করতে প্রয়োজনীয় কনফিগারেশন এবং সেটআপ নিয়ে আলোচনা করব।
Step 1: FastAPI অ্যাপ তৈরি
প্রথমে একটি সহজ FastAPI অ্যাপ তৈরি করি:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, Production!"}
এটি একটি সাধারণ অ্যাপ যা একটি রুট এন্ডপয়েন্ট প্রদান করে। প্রোডাকশনে যাওয়ার আগে, আমরা বিভিন্ন কনফিগারেশন এবং উন্নত সেটআপ সম্পন্ন করব।
Step 2: Uvicorn এর সাথে অ্যাপ চালানো
প্রোডাকশন পরিবেশে Uvicorn একটি হালকা, দ্রুত এবং কার্যকর ASGI সার্ভার হিসেবে FastAPI অ্যাপ্লিকেশন চালাতে ব্যবহৃত হয়। Uvicorn এর সাথে Gunicorn বা Daphne ব্যবহার করলে অ্যাপ আরও ভালোভাবে স্কেল এবং ম্যানেজ করা যায়।
Uvicorn ইনস্টল:
pip install uvicorn
Uvicorn দিয়ে অ্যাপ চালানো:
uvicorn main:app --host 0.0.0.0 --port 80 --workers 4
এখানে:
--host 0.0.0.0: অ্যাপটি সমস্ত নেটওয়ার্ক থেকে অ্যাক্সেসযোগ্য হবে।--port 80: HTTP স্ট্যান্ডার্ড পোর্ট 80 এ অ্যাপ চালানো হবে।--workers 4: ৪টি ওয়াকার ব্যবহার করা হবে, যা প্রোডাকশন পরিবেশে অ্যাপ্লিকেশনকে স্কেল করতে সাহায্য করে।
Step 3: Gunicorn + Uvicorn Worker ব্যবহার করা
প্রোডাকশনে, Gunicorn ব্যবহার করা হয়, যা একটি উচ্চ-দক্ষতার WSGI সার্ভার, এবং Uvicorn এর সাথে কাজ করে অ্যাসিঙ্ক্রোনাস ফিচার সাপোর্ট দেয়।
Gunicorn ইনস্টল:
pip install gunicorn
Gunicorn + Uvicorn Worker দিয়ে অ্যাপ চালানো:
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:80
এখানে:
-w 4: ৪টি ওয়াকার (processes) ব্যবহার করা হবে।-k uvicorn.workers.UvicornWorker: Uvicorn এর ওয়াকার ব্যবহার করা হবে।--bind 0.0.0.0:80: অ্যাপ 80 পোর্টে এবং সমস্ত নেটওয়ার্কে অ্যাক্সেসযোগ্য হবে।
Step 4: Reverse Proxy হিসেবে Nginx কনফিগার করা
প্রোডাকশন পরিবেশে, Nginx সাধারণত অ্যাপ্লিকেশন সার্ভারের জন্য একটি reverse proxy হিসেবে ব্যবহৃত হয়। এটি HTTPS সিকিউরিটি এবং ভারী লোড পরিচালনা করতে সাহায্য করে।
Nginx কনফিগারেশন উদাহরণ:
Nginx ইনস্টল করুন:
sudo apt update sudo apt install nginxNginx কনফিগারেশন ফাইল তৈরি করুন:
/etc/nginx/sites-available/your-appনামে একটি কনফিগারেশন ফাইল তৈরি করুন:server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }Nginx কনফিগারেশন সক্রিয় করুন:
sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
এখন, Nginx আপনার FastAPI অ্যাপ্লিকেশনকে প্রোডাকশন পরিবেশে রিভার্স প্রক্সি হিসেবে পরিচালনা করবে।
Step 5: HTTPS কনফিগারেশন (Let's Encrypt)
প্রোডাকশনে HTTPS ব্যবহার করা জরুরি। Let's Encrypt একটি ফ্রি সার্টিফিকেট প্রদানকারী এবং Certbot এর মাধ্যমে HTTPS সক্রিয় করা যায়।
Certbot ইনস্টল:
sudo apt install certbot python3-certbot-nginx
Certbot দিয়ে HTTPS সার্টিফিকেট গ্রহণ:
sudo certbot --nginx -d your-domain.com
এটি আপনার Nginx কনফিগারেশন আপডেট করবে এবং HTTPS সক্রিয় করবে।
Step 6: Logging এবং Monitoring
প্রোডাকশন পরিবেশে অ্যাপ্লিকেশনের Logging এবং Monitoring অত্যন্ত গুরুত্বপূর্ণ। FastAPI তে Logging এবং Uvicorn লগ ব্যবস্থাপনা খুব সহজ।
Logging কনফিগারেশন:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.get("/items/")
def read_item():
logger.info("Item route accessed")
return {"message": "Item accessed"}
এখানে, FastAPI লগিং এর জন্য Python এর বিল্ট-ইন logging লাইব্রেরি ব্যবহার করা হয়েছে।
Prometheus এবং Grafana ব্যবহারের মাধ্যমে Monitoring:
আপনি Prometheus এবং Grafana ব্যবহার করে আপনার FastAPI অ্যাপ্লিকেশন মনিটর করতে পারেন। Prometheus থেকে মেট্রিক্স সংগ্রহ এবং Grafana দিয়ে ড্যাশবোর্ডে দেখানো হয়।
Step 7: Scaling and Load Balancing
প্রোডাকশন পরিবেশে অ্যাপ স্কেল করার জন্য আপনি Load Balancer ব্যবহার করতে পারেন, যেমন HAProxy, Nginx, অথবা Cloud Providers (AWS, Azure) এর লোড ব্যালান্সিং সার্ভিস।
Scaling example:
gunicorn -w 8 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000
এখানে -w 8 নির্দেশ করে যে ৮টি ওয়াকার প্রসেস চালানো হবে, যা অ্যাপকে উচ্চ লোড হ্যান্ডেল করার ক্ষমতা দেবে।
Step 8: Security Best Practices
FastAPI অ্যাপ্লিকেশনটি প্রোডাকশন পরিবেশে নিরাপদ রাখতে কিছু গুরুত্বপূর্ণ নিরাপত্তা কনফিগারেশন করা উচিত।
- SQL Injection, XSS এবং CSRF প্রতিরোধ করতে সঠিক সিকিউরিটি কনফিগারেশন।
- OAuth2, JWT (JSON Web Tokens) ব্যবহার করে অথেনটিকেশন এবং অথোরাইজেশন কনফিগারেশন।
- HTTP headers যেমন
X-Frame-Options,X-XSS-Protection, এবংStrict-Transport-Securityকনফিগারেশন। - CORS (Cross-Origin Resource Sharing) কনফিগারেশন।
- Firewall এবং DDOS Protection।
Step 9: Auto Restart with Systemd
প্রোডাকশনে অ্যাপ্লিকেশন চালানোর সময় auto-restart নিশ্চিত করা উচিত। systemd ব্যবহার করে অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে পুনরায় চালু করা যায়।
systemd service file:
Service ফাইল তৈরি করা:
/etc/systemd/system/your-app.service[Unit] Description=FastAPI Application After=network.target [Service] User=your-user WorkingDirectory=/path/to/your/app ExecStart=/path/to/your/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000 Restart=always [Install] WantedBy=multi-user.targetsystemd সেবা চালু করা:
sudo systemctl start your-app sudo systemctl enable your-app
FastAPI অ্যাপ্লিকেশনকে প্রোডাকশন পরিবেশে scalable, secure, এবং reliable করার জন্য উপরে বর্ণিত কনফিগারেশনগুলো ব্যবহার করতে পারেন। Uvicorn, Gunicorn, Nginx, HTTPS, এবং Load Balancing সহ Logging এবং Monitoring অ্যাপ্লিকেশনটি প্রোডাকশন পরিবেশে পরিচালনা এবং মনিটরিংকে সহজ করে তোলে।
Read more